#pragma once
#include "Socket.hpp"
#include <functional>
#include <memory>
#include <pthread.h>

class TcpServer;

// using func_t = std::function<std::string(std::string &inbuffer, bool *)>;
using func_t = std::function<std::string(Socket *)>;

class ThreadData
{
public:
    ThreadData(TcpServer *this_server, Socket *this_socket) : _socket(this_socket), _this(this_server)
    {
    }

    ~ThreadData()
    {
    }

public:
    Socket *_socket;
    TcpServer *_this;
};

class TcpServer
{
public:
    TcpServer(func_t handler_function) : _socket(new TcpSocket()), _function(handler_function)
    {
    }

    ~TcpServer()
    {
    }

    static void *ThreadRun(void *date)
    {
        pthread_detach(pthread_self());
        ThreadData *td = static_cast<ThreadData *>(date);
        // std::string inbuffer;
        // td->_socket->Recv(&inbuffer, sizeof(inbuffer));
        while (true)
        {
            bool ok;
            std::string send_message = td->_this->_function(td->_socket);
            td->_socket->Send(send_message);
        }
        td->_socket->CloseSocket();
        delete td->_socket;
        delete td;
        return nullptr;
    }

    void Init(uint16_t port)
    {
        _socket->BulidListenSocketMethod(port);
    }

    void Start()
    {
        while (true)
        {
            std::string peerip;
            uint16_t peerport;
            Socket *newsocket = _socket->AcceptConnection(&peerip, &peerport);
            std::cout << "获取一个新连接, sockfd: " << newsocket->GetSockfd() << " client info: [" << peerip << ":" << peerport << "]" << std::endl;
            pthread_t tid;
            ThreadData *td = new ThreadData(this, newsocket);
            pthread_create(&tid, nullptr, ThreadRun, td);
        }
    }

private:
    Socket *_socket;

public:
    func_t _function;
};